﻿// *********************************************************************
// [DCOM Productions]
// [Copyright (C) DCOM Productions All rights reserved.]
// *********************************************************************

namespace BitFlex.Windows.Forms.Design {
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ComponentModel.Design;
    using System.Windows.Forms.Design;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Drawing.Design;
    using System.Drawing;

    /// <summary>
    /// DesignerActionList for <see cref="BitFlex.Windows.Forms.Design.WizardDesigner"/>
    /// </summary>
    public class WizardActionList : DesignerActionList, ITypeDescriptorContext, IWindowsFormsEditorService {
        /// <summary>
        /// Initializes a new instance of the BitFlex.Windows.Forms.Design.WizardActionList class
        /// </summary>
        /// <param name="component">Base Component</param>
        public WizardActionList(IComponent component) 
            : base(component) {
            m_HostService = component.Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
            m_ComponentService = component.Site.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
            m_PropertyDescriptor = TypeDescriptor.GetProperties(component)["Pages"];
            m_UndockedSize = new System.Drawing.Size(250, 250);
        }

        #region Fields

        private IDesignerHost m_HostService;
        private IComponentChangeService m_ComponentService;
        private PropertyDescriptor m_PropertyDescriptor;
        private Size m_UndockedSize;

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the SelectedPage of the wizard being designed
        /// </summary>
        public WizardPage SelectedPage {
            get {
                Wizard wizard = Component as Wizard;
                return wizard.SelectedPage;
            }
            set {
                Wizard wizard = Component as Wizard;
                wizard.SelectedPage = value;
            }
        }

        #endregion

        #region Methods

        private void Dock() {
            Control control = Component as Control;
            if (control != null) {
                m_UndockedSize = control.Size;
                control.Dock = DockStyle.Fill;
                DesignerActionUIService service;
                service = (DesignerActionUIService)GetService(typeof(DesignerActionUIService));
                service.Refresh(Component);
                control.Refresh();
                control.Select();
            }
        }

        private void EditPages() {
            UITypeEditor editor = (UITypeEditor)m_PropertyDescriptor.GetEditor(typeof(UITypeEditor));
            editor.EditValue(this, this, ((Wizard)Component).Pages);
        }

        public override DesignerActionItemCollection GetSortedActionItems() {
            DesignerActionItemCollection collection = new DesignerActionItemCollection();
            if (((Control)Component).Dock == DockStyle.Fill) {
                collection.Add(new DesignerActionMethodItem(this, "Undock", "Undock from parent container"));
            }
            else {
                collection.Add(new DesignerActionMethodItem(this, "Dock", "Dock in parent container"));
            }
            collection.Add(new DesignerActionMethodItem(this, "EditPages", "Edit Pages...", true));
            collection.Add(new DesignerActionHeaderItem("Change the active WizardPage", string.Empty));
            collection.Add(new DesignerActionPropertyItem("SelectedPage", "Active Page"));
            return collection;
        }

        private void Undock() {
            Control control = Component as Control;
            if (control != null) {
                control.Dock = DockStyle.None;
                if (m_UndockedSize != null) {
                    control.Size = m_UndockedSize;
                }
                DesignerActionUIService service;
                service = (DesignerActionUIService)GetService(typeof(DesignerActionUIService));
                service.Refresh(Component);
                control.Refresh();
                control.Select();
            }
        }
 
        #endregion

        #region ITypeDescriptorContext Members

        IContainer ITypeDescriptorContext.Container {
            get {
                return this.Component.Site.Container;
            }
        }

        object ITypeDescriptorContext.Instance {
            get {
                return this.Component;
            }
        }

        void ITypeDescriptorContext.OnComponentChanged() {
            object value = ((Wizard)this.Component).Pages;
            m_ComponentService.OnComponentChanged(this.Component, m_PropertyDescriptor, value, value);
        }

        bool ITypeDescriptorContext.OnComponentChanging() {
            m_ComponentService.OnComponentChanging(this.Component, m_PropertyDescriptor);
            return true;
        }

        PropertyDescriptor ITypeDescriptorContext.PropertyDescriptor {
            get {
                return m_PropertyDescriptor;
            }
        }

        #endregion

        #region IServiceProvider Members

        object IServiceProvider.GetService(Type serviceType) {
            if (serviceType.Equals(typeof(IWindowsFormsEditorService))) {
                return this;
            }
            else {
                return m_HostService.GetService(serviceType);
            }
        }

        #endregion

        #region IWindowsFormsEditorService Members

        void IWindowsFormsEditorService.CloseDropDown() {
            throw new NotImplementedException();
        }

        void IWindowsFormsEditorService.DropDownControl(Control control) {
            throw new NotImplementedException();
        }

        DialogResult IWindowsFormsEditorService.ShowDialog(Form dialog) {
            return dialog.ShowDialog();
        }

        #endregion
    }
}
